package com.apchernykh.rozhlasapp.podcast;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.apchernykh.rozhlasapp.utils.ConditionalLog;
import com.apchernykh.rozhlasapp.utils.DateUtil;
import com.apchernykh.types.PodcastFeedInfo;
import com.apchernykh.types.Show;

public class PodcastFeedHandler extends DefaultHandler {

	PodcastFeedInfo mFeedInfo;

	boolean mParsingPodcastTitle = false;
	boolean mParsingPodcastDescription = false;

	boolean mParsingItem = false;
	boolean mParsingItemTitle = false;
	boolean mParsingItemDescription = false;
	boolean mParsingItemSummary = false;
	boolean mParsingItemPubDate = false;

	String mCurrentItemTitle = null;
	StringBuilder mCurrentItemDescription = new StringBuilder();
	StringBuilder mCurrentItemSummary = new StringBuilder();
	String mCurrentItemEnclosure = null;
	String mCurrentItemPubDate = null;
	public int mUrlsCount = 0;
	public List<Show> mLocalShowsList = new LinkedList<Show>();
	final static Pattern mNameDatePattern = Pattern.compile("(.*)\\([ :.0123456789]*\\)");

	public PodcastFeedHandler(PodcastFeedInfo iInfo) {
		mFeedInfo = iInfo;
	}

	@Override
	public void characters(char[] iBuffer, int iOffset, int iLength)
			throws SAXException {
		if (mParsingItemTitle) {
			mCurrentItemTitle = String.valueOf(iBuffer, iOffset, iLength);
		} else if (mParsingItemDescription) {
			mCurrentItemDescription.append(iBuffer, iOffset, iLength);
		} else if (mParsingItemSummary) {
			mCurrentItemSummary.append(iBuffer, iOffset, iLength);
		} else if (mParsingPodcastTitle) {
			mFeedInfo.setTitle(String.valueOf(iBuffer, iOffset, iLength));
		} else if (mParsingPodcastDescription) {
			mFeedInfo.setDescription(String.valueOf(iBuffer, iOffset, iLength));
		} else if (mParsingItemPubDate) {
			mCurrentItemPubDate = String.valueOf(iBuffer, iOffset, iLength);
		}
	}

	@Override
	public void startElement(String iUri, String iLocalName, String iName,
			Attributes attributes) throws SAXException {
		if ("item".equals(iLocalName)) {
			mParsingItem = true;
		} else if (mParsingItem && "title".equals(iLocalName)) {
			mParsingItemTitle = true;
		} else if (mParsingItem && "enclosure".equals(iLocalName)) {
			mCurrentItemEnclosure = attributes.getValue("url");
			mUrlsCount++;
		} else if (mParsingItem && "description".equals(iLocalName)) {
			mParsingItemDescription = true;
		} else if (mParsingItem && "summary".equals(iLocalName)) {
			mParsingItemSummary = true;
		} else if (!mParsingItem && "title".equals(iLocalName)) {
			mParsingPodcastTitle = true;
		} else if (!mParsingItem && "description".equals(iLocalName)) {
			mParsingPodcastDescription = true;
		} else if (mParsingItem && "pubDate".equals(iLocalName)) {
			mParsingItemPubDate = true;
		}
	}

	@Override
	public void endElement(String iUri, String iLocalName, String iName)
			throws SAXException {
		if ("item".equals(iLocalName)) {
			mParsingItem = false;
			Show aNewShow = new Show();
			try {
				Matcher aNameDateMatch = mNameDatePattern.matcher(mCurrentItemTitle);
				if (aNameDateMatch.matches()) {
					mCurrentItemTitle = aNameDateMatch.group(1);
				}
			} catch (IllegalStateException e) {
				ConditionalLog.e("could not strip date from string "
						+ mCurrentItemTitle);
			}
			aNewShow.setTitle(mCurrentItemTitle);
			aNewShow.setUrl(mCurrentItemEnclosure);

			if (mCurrentItemPubDate != null && mCurrentItemPubDate.length() > 0) {
				Date aPodcastPublicationDate = DateUtil
						.parseRfc822DateString(mCurrentItemPubDate);
				// Date pubDate = new Date();
				// try {
				// pubDate = mCzechDateFormat.parse(currentItemPubDate);
				// } catch (Throwable e) {
				// ConditionalLog.e(this.toString(),
				// "Unable to parse date, will return now() :)", e);
				// }
				aNewShow.setDate(aPodcastPublicationDate);
			}

			if (mCurrentItemSummary.length() > 0) {
				aNewShow.setDescription(mCurrentItemSummary.toString());
			} else if (mCurrentItemDescription.length() > 0) {
				aNewShow.setDescription(mCurrentItemDescription.toString());
			}

			if (aNewShow.getUrl() != null) {
				mLocalShowsList.add(aNewShow);
			}

			mCurrentItemTitle = null;
			mCurrentItemEnclosure = null;
			mCurrentItemDescription = new StringBuilder();
			mCurrentItemSummary = new StringBuilder();
		} else if (mParsingItem && "title".equals(iLocalName)) {
			mParsingItemTitle = false;
		} else if (mParsingItem && "description".equals(iLocalName)) {
			mParsingItemDescription = false;
		} else if (mParsingItem && "summary".equals(iLocalName)) {
			mParsingItemSummary = false;
		} else if (!mParsingItem && "title".equals(iLocalName)) {
			mParsingPodcastTitle = false;
		} else if (!mParsingItem && "description".equals(iLocalName)) {
			mParsingPodcastDescription = false;
		} else if (mParsingItem && "pubDate".equals(iLocalName)) {
			mParsingItemPubDate = false;
		}
	}
}
